from pony import orm
import sys
from pathlib import Path
import uuid
from datetime import datetime

from .config import settings


orm.set_sql_debug(False)

db = orm.Database()
# db.bind(
#     provider='sqlite',
#     filename=str(Path(sys.argv[0]).parent / 'db.sqlite'),
#     create_db=True
# )
db.bind(
    provider='postgres',
    host=settings.PG_HOST,
    port=settings.PG_PORT,
    database=settings.PG_DATABASE,
    user=settings.PG_USERNAME,
    password=settings.PG_PASSWORD,
)

# db.bind(
#     provider='postgres',
#     host='192.168.10.136',
#     port=5432,
#     database='dev-inphile-alg-zhongzhi',
#     user='postgres',
#     password='pg123456',
# )


def generate_uuid():
    return uuid.uuid4().hex


################
# place all entities below
################

# Required, 必须有值的字段, 值不能是null或者''
# Optional, 值可以为null或者''的字段, 字符字段默认为'', 其它字段默认为null

# !!!
# sqlite, postgresql, 时间字段可以附加选项 sql_type='TIMESTAMP WITH TIME ZONE'
# mysql, 时间字段不需要附加该选项


# class Example(db.Entity):
#     _table_ = 'example'


# 甲方银行、银行区域、银行区域代码、支行、支行代码关系映射表
class Bank(db.Entity):
    _table_ = 'inphile_big_data_bank'

    id = orm.PrimaryKey(str, default=generate_uuid)
    bank_branch_name = orm.Optional(str)  # 支行
    bank_branch_code = orm.Optional(str)  # 支行代码
    bank_name = orm.Optional(str)  # 甲方银行名称
    bank_code = orm.Optional(str)  # 甲方银行代码
    province = orm.Optional(str)  # 银行区域
    province_code = orm.Optional(str)  # 银行区域代码
    city = orm.Optional(str)  # 银行区域
    city_code = orm.Optional(str)  # 银行区域代码
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 标准银行名称与甲方银行名称、银行代码、银行区域、银行区域代码的关系映射
class BankMapping(db.Entity):
    _table_ = 'inphile_big_data_bank_mapping'

    id = orm.PrimaryKey(str, default=generate_uuid)
    bank_number_info = orm.Optional(str)
    bank_standard_name = orm.Optional(str)  # 标准银行名称
    bank_mapping_name = orm.Optional(str)  # 甲方银行名称
    bank_mapping_code = orm.Optional(str)  # 甲方银行代码
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 科室映射库
class DepartmentMapping(db.Entity):
    _table_ = 'inphile_big_data_department_customer_mapping'

    id = orm.PrimaryKey(str, default=generate_uuid)
    standard_name = orm.Optional(str)
    mapping_name = orm.Optional(str)
    mapping_code = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())
    last_modified = orm.Optional(datetime, volatile=True)


class DepartmentNickname(db.Entity):
    _table_ = 'inphile_big_data_department_biecheng'

    id = orm.PrimaryKey(str, default=generate_uuid)
    name = orm.Required(str)
    another_name = orm.Required(str)
    version = orm.Required(str)
    update_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 以医院为单位的费用名称累计库
class Hospital(db.Entity):
    _table_ = 'inphile_big_data_hospital'

    id = orm.PrimaryKey(str, default=generate_uuid)
    hospital_id = orm.Optional(str)
    hospital = orm.Optional(str)
    img_original_name = orm.Optional(str)
    full_name = orm.Optional(str)
    customer_name = orm.Optional(str)
    nhsa_name = orm.Optional(str)
    nhsa_code = orm.Optional(str)
    price = orm.Optional(str)
    medical_insurance_type = orm.Optional(str)
    ratio = orm.Optional(str)
    type = orm.Optional(str)
    remark = orm.Optional(str)
    img_path = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 以国家为单位的费用名称累计库
class Country(db.Entity):
    _table_ = 'inphile_big_data_country'

    id = orm.PrimaryKey(str, default=generate_uuid)
    full_name = orm.Optional(str)
    customer_name = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 医院映射库
class HospitalMapping(db.Entity):
    _table_ = 'inphile_big_data_hospital_mapping'

    id = orm.PrimaryKey(str, default=generate_uuid)
    hospital_id = orm.Optional(str)
    hospital_name_seal = orm.Optional(str)
    hospital_name_bill = orm.Optional(str)
    hospital_name_nhsa = orm.Optional(str)
    remark = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


class DingDianHospital(db.Entity):
    _table_ = 'inphile_big_data_hospital_coding'

    id = orm.PrimaryKey(str, default=generate_uuid)
    hospital_id = orm.Optional(str)
    hospital_name_nhsa = orm.Optional(str)
    city = orm.Optional(str)
    province = orm.Optional(str)
    address = orm.Optional(str)
    level = orm.Optional(str)
    hospital_type = orm.Optional(str)
    remark = orm.Optional(str)
    # 创建时间
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())
    # 最近修改时间
    last_modified = orm.Optional(datetime, volatile=True)


class HospitalNickname(db.Entity):
    _table_ = 'inphile_big_data_hospital_biecheng'

    name = orm.Required(str)
    another_name = orm.Required(str)


class ProvinceCity(db.Entity):
    _table_ = 'inphile_big_data_province_city'

    province_name = orm.Optional(str)
    city_name = orm.Optional(str)


class Area(db.Entity):
    _table_ = 'inphile_big_data_area'

    city_name = orm.Optional(str)
    type = orm.Optional(int)


# 联想输入库
class AssociateInput(db.Entity):
    _table_ = 'inphile_big_data_associate_input'

    id = orm.PrimaryKey(str, default=generate_uuid)
    hospital = orm.Optional(str)
    name = orm.Required(str)
    type = orm.Optional(str)
    num = orm.Required(int, default=0)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())
    last_modified = orm.Optional(datetime, volatile=True)


# 疾病直接映射表
class DiseaseDirectMapping(db.Entity):
    _table_ = 'inphile_big_data_disease_direct_mapping'

    id = orm.PrimaryKey(str, default=generate_uuid)
    name = orm.Optional(str)
    customer_name = orm.Optional(str)
    assayer = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 甲方疾病表
class DiseaseCustomerMapping(db.Entity):
    _table_ = 'inphile_big_data_disease_customer_mapping'

    id = orm.PrimaryKey(str, default=generate_uuid)
    disease_code = orm.Optional(str)
    disease_name = orm.Optional(str)
    customer_name = orm.Optional(str)
    outsource = orm.Optional(str)
    remark = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 归一化甲方映射表
class DiseaseNormalMapping(db.Entity):
    _table_ = 'inphile_big_data_disease_normal_mapping'

    id = orm.PrimaryKey(str, default=generate_uuid)
    normal_name = orm.Optional(str)
    normal_code = orm.Optional(str)
    customer_code = orm.Optional(str)
    customer_name = orm.Optional(str)
    remark = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 卷三疾病表
class DiseaseThirdVolume(db.Entity):
    _table_ = 'inphile_big_data_disease_third_volume'

    id = orm.PrimaryKey(str, default=generate_uuid)
    name = orm.Optional(str)
    remark = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


class DiseaseStandardICD4(db.Entity):
    _table_ = 'inphile_big_data_jibing_fenlei_icd4_kv'

    disease_code = orm.Required(str)
    disease_name = orm.Required(str)


class DiseaseStandardICD6(db.Entity):
    _table_ = 'inphile_big_data_jibing_fenlei_icd6_kv'

    disease_code = orm.Required(str)
    disease_name = orm.Required(str)


class DiseaseNicknameICD4(db.Entity):
    _table_ = 'inphile_big_data_disease_nickname_icd4'
    id = orm.PrimaryKey(str, default=generate_uuid)
    disease_code = orm.Required(str)
    disease_name = orm.Required(str)
    processed_name = orm.Required(str)


class DiseaseNicknameICD6(db.Entity):
    _table_ = 'inphile_big_data_disease_nickname_icd6'
    id = orm.PrimaryKey(str, default=generate_uuid)
    disease_code = orm.Required(str)
    disease_name = orm.Required(str)
    processed_name = orm.Required(str)


class DiseaseJuanSan(db.Entity):
    _table_ = 'inphile_big_data_jibing_juansan'

    id = orm.PrimaryKey(str, default=generate_uuid)
    name = orm.Required(str)
    main_code = orm.Optional(str)
    morph_code = orm.Optional(str)
    see_also = orm.Optional(str)
    rank0 = orm.Optional(str)
    rank1 = orm.Optional(str)
    rank2 = orm.Optional(str)
    rank3 = orm.Optional(str)
    rank4 = orm.Optional(str)
    rank5 = orm.Optional(str)
    rank6 = orm.Optional(str)


# 药品归一化库，包含标准名字、同义词已经标准名称的切词等
class MedicineNormalize(db.Entity):
    _table_ = 'inphile_big_data_medicine_normalize'

    id = orm.PrimaryKey(str, default=generate_uuid)
    base_code = orm.Optional(str)
    permission_code = orm.Optional(str)
    nhsa_code = orm.Optional(str)
    nhsa_name = orm.Optional(str)
    other_name = orm.Optional(str)
    trade_name = orm.Optional(str)
    main_constituent = orm.Optional(str)
    dosage_form = orm.Optional(str)
    sub_name1 = orm.Optional(str)
    sub_name2 = orm.Optional(str)
    sub_name3 = orm.Optional(str)
    strength = orm.Optional(str)
    manufacturer = orm.Optional(str)
    special_symbol = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 中药药品归一化库，包含标准名字、同义词
class ChineseMedicineNormalize(db.Entity):
    _table_ = 'inphile_big_data_chinese_medicine_normalize'

    id = orm.PrimaryKey(str, default=generate_uuid)
    piecescode = orm.Optional(str)
    name = orm.Optional(str)
    other_name = orm.Optional(str)
    medicinalmaterialsname = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 药品切词库，按照主成分\剂型\规格\酸根盐基等进行切词
class MedicineCutWord(db.Entity):
    _table_ = 'inphile_big_data_medicine_cutword'

    id = orm.PrimaryKey(str, default=generate_uuid)
    name = orm.Optional(str)  # 药品名称
    cut_word_name = orm.Optional(str)  # 切词名称
    cut_word_property = orm.Optional(str)  # 切词的类型（主成分\剂型\规格\酸根盐基等）
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 医疗服务归一化库，包含标准名字、同义词
class MedicalServiceNormalize(db.Entity):
    _table_ = 'inphile_big_data_service_normalize'

    id = orm.PrimaryKey(str, default=generate_uuid)
    nhsa_code = orm.Optional(str)
    standard_name = orm.Optional(str)
    other_name = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 医疗服务切词库，按照25个属性进行切词
class MedicalServiceCutWord(db.Entity):
    _table_ = 'inphile_big_data_medical_service_cutword'

    id = orm.PrimaryKey(str, default=generate_uuid)
    name = orm.Optional(str)  # 医疗服务名称
    cut_word_name = orm.Optional(str)  # 切词名称
    cut_word_type = orm.Optional(str)  # 切词的类型（标准、别称、多错漏）
    cut_word_property = orm.Optional(str)  # 切词的属性（共25种）
    cut_word_property_num = orm.Optional(int)  # 这条医疗服务名称包含多少种切词属性
    all_property_num = orm.Optional(int)  # 总共有多少条切词属性
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 医疗服务归一化库，包含标准名字、同义词
class ConsumableNormalize(db.Entity):
    _table_ = 'inphile_big_data_consumable_normalize'

    id = orm.PrimaryKey(str, default=generate_uuid)
    nhsa_code = orm.Optional(str)
    first_level_name = orm.Optional(str)
    second_level_name = orm.Optional(str)
    third_level_name = orm.Optional(str)
    fourth_level_name = orm.Optional(str)
    common_name = orm.Optional(str)
    other_name = orm.Optional(str)
    other_key_word = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


# 以城市为单位的医保三目录扣费比例
class MedicalInsuranceCatalogue(db.Entity):
    _table_ = 'inphile_big_data_medical_insurance_catalogue'

    id = orm.PrimaryKey(str, default=generate_uuid)
    code = orm.Optional(str)  # 项目编码
    name = orm.Required(str)  # 项目名称
    nick_name = orm.Optional(str)  # 项目别名
    major_item = orm.Optional(str)  # 医疗项目分类（大项）
    unit_price = orm.Optional(str)  # 单价
    medical_insurance_type = orm.Optional(str)  # 医保类型
    self_pay_proportion_worker = orm.Optional(str)  # 城镇职工自负比例
    self_pay_proportion_resident = orm.Optional(str)  # 城乡居民自负比例
    self_pay_proportion_student = orm.Optional(str)  # 学生自负比例
    self_pay_proportion_industrial_injury = orm.Optional(str)  # 工伤自负比例
    self_pay_proportion_maternity = orm.Optional(str)  # 生育自负比例
    price_limit_sign = orm.Optional(str)  # 限价标志
    price_limit_first_level = orm.Optional(str)  # 一级限价
    price_limit_second_level = orm.Optional(str)  # 二级限价
    price_limit_third_level = orm.Optional(str)  # 三级限价
    price_limit_no_graded = orm.Optional(str)  # 未分级限价
    unreasonable_expense_sign = orm.Optional(str)  # 不合理费用标志
    remark = orm.Optional(str)  # 备注
    out_of_social_security_catalogue_sign = orm.Optional(str)  # 社保外目录标志
    origin_attribute = orm.Optional(str)  # 产地属性
    is_invalid = orm.Optional(str)  # 是否作废
    entry_into_force_time = orm.Optional(str)  # 生效时间
    termination_time = orm.Optional(str)  # 终止时间
    social_security_catalogue_code = orm.Optional(str)  # 社保目录编码
    type = orm.Optional(str)  # 类型（药品、医疗服务、耗材）
    city = orm.Optional(str)  # 城市名称


# 部件库（药品特有词汇、医疗服务特有词汇、耗材特有词汇、剂型等，主要用于费用明细的分类）
class Component(db.Entity):
    _table_ = 'inphile_big_data_component'

    id = orm.PrimaryKey(str, default=generate_uuid)
    name = orm.Optional(str)
    type = orm.Optional(str)
    creation_time = orm.Required(datetime, volatile=True, default=datetime.now())


################
# place all entities above
################


# all entities connected to the database must be defined before calling generate_mapping()
# if the tables do not already exist, then they will be created
db.generate_mapping(create_tables=True)
